import React, { useContext } from 'react'
import { Item, FieldContext } from '@amazebird/antd-schema-form'
import { DeleteOutlined, ArrowUpOutlined, ArrowDownOutlined, PlusOutlined } from '@ant-design/icons'
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'
import { isFunction, isObject, isString } from 'lodash-es'
import { Button, Row, Col, Tooltip, Form } from 'antd'
import { UnorderedListOutlined } from '@ant-design/icons';
import './array.less'
// import { element } from 'prop-types'

function changePosition(array, sourceIndex, destinationIndex) {
  if (sourceIndex === destinationIndex) return array
  const copyArr = [...array]
  const source = copyArr[sourceIndex]
  copyArr.splice(sourceIndex > destinationIndex ? destinationIndex : destinationIndex + 1, 0, source)
  const deleteIndex =
    sourceIndex > destinationIndex ? sourceIndex + 1 : sourceIndex
  copyArr.splice(deleteIndex, 1)
  return copyArr
}

function DelButton({ remove, index, options, fields, actions }) {
  const { element } = options
  return (
    <div >
      <Tooltip title="删除本行">
        <div onClick={() => remove(index)} className="array-operator">
          {
            element ?? <DeleteOutlined />
          }
        </div>
      </Tooltip>
    </div>
  )
}

function UpButton({ move, index, options, fields, actions }) {
  const { element } = options
  function moveUp() {
    if (index > 0) {
      move(index, index - 1)
    }
  }
  return (
    <div>
      <Tooltip title="向上移动">
        <div onClick={moveUp} className="array-operator">
          {element ?? <ArrowUpOutlined />}
        </div>
      </Tooltip>
    </div>
  )
}

function DownButton({ move, index, options, fields, actions }) {
  const { element } = options
  function moveDown() {
    if (index < fields.length - 1) {
      move(index, index + 1)
    }
  }
  return (
    <div>
      <Tooltip title="向下移动">
        <div onClick={moveDown} className="array-operator">
          {element ?? <ArrowDownOutlined />}
        </div>
      </Tooltip>
    </div>
  )
}

function DragButton({ options, ...dragHandleProps }) {
  const { element } = options
  const dom = element ?? <UnorderedListOutlined />
  return (
    <Tooltip title="拖拽本行">
      <div className="array-operator" {...dragHandleProps}>{dom}</div>
    </Tooltip>
  )
}

function AddButton({ options, add, actions, columns }) {
  const { icon = <PlusOutlined />, text = '添加', span = 24, pull, push, beforeAction, afterAction } = options
  const addItem = async () => {
    const goahead = await beforeAction?.(actions)
    add()
    await afterAction?.(actions)
  }
  return (
    <Row>
      <Col pull={pull} push={push} span={span}>
        <Button onClick={addItem} type="dashed" block>
          {icon}{text}
        </Button>
      </Col>
    </Row>
  )
}

function ArrayItem(props) {
  const { columns,
    fields,
    operation: { add, remove, move },
    operation,
    meta: { errors },
    recordAction = [],
    showIndex = {},
    add: addAction = {}
  } = props
  console.log('ArrayItem-props---', props)
  const { form, parentField } = useContext(FieldContext)
  console.info('props', parentField)
  const { $name, $path } = parentField
  const { headerLabel: indexHeaderLabel, label: indexLabel, width: indexWidth } = showIndex
  let addButtonProps = {}
  if (isObject(addAction)) {
    addButtonProps = addAction
  }
  let dragDom

  function onBeforeCapture() {
    dragDom.style.height = dragDom.offsetHeight + 'px'
  }

  function onDragEnd(data) {
    const { source, destination } = data
    if (
      source.droppableId === destination.droppableId &&
      source.index !== destination.index
    ) {
      const fieldData = form.getFieldValue($name)
      const result = changePosition(fieldData, source.index, destination.index)
      console.log('arrayitem--changeposition--result', result)
      form.setFields([{ name: $name, value: result }])
      dragDom.style.height = 'auto'
    }
  }
  const operationElement = columns.map(({ label, span, key, textAlign = 'left' }, index) => {
    const style = index === 0 ? { paddingLeft: 0 } : {}
    return (
      // @ts-ignore
      <Col style={{ ...style, textAlign }} span={span} key={key} >
        <label>{label}</label>
      </Col>
    )
  }).concat([
    <Col flex='1 0 150px' key={JSON.stringify(columns)}>
      <label />
    </Col>
  ])

  const indexElement = showIndex ? (
    <Col flex={`0 0 ${indexWidth || 60}px`} key='orderIndex'>
      <label>
        {indexHeaderLabel || ''}
      </label>
    </Col>
  ) : null
  console.log('fields', fields)
  return (
    <div className="schema-form-array">
      <div className="array-title">
        <Row gutter={24} wrap={false} style={{ flex: 1, margin: 0 }}>
          {
            [indexElement, ...operationElement]
          }
        </Row>
      </div>
      <div
        ref={(dom) => {
          dragDom = dom
        }}
        style={{ display: 'block' }}
      >
        <DragDropContext
          onDragEnd={onDragEnd}
          onBeforeCapture={onBeforeCapture}
        >
          <Droppable droppableId={$path}>
            {(provided) => {
              const { innerRef } = provided
              return (
                <div ref={innerRef} >
                  {fields.map((field, index) => {
                    return (
                      <Draggable
                        key={field.key}
                        draggableId={`${field.fieldKey}`}
                        index={index}
                      >
                        {
                          (provided) => {
                            return (
                              <div
                                key={field.key}
                                ref={provided.innerRef}
                                className="clear"
                                {...provided.draggableProps}
                              >
                                <Item {...field} wrapperCol={{ span: 24 }} className="array-item" >
                                  <div className="array-item-row" >
                                    <Row wrap={false} gutter={24} style={{ flex: 1, margin: 0 }}>
                                      {showIndex && <Col flex={`0 0 ${indexWidth || 60}px`} style={{ lineHeight: '32px' }}>{isFunction(indexLabel) ? indexLabel(index) : indexLabel || index}</Col>}
                                      {
                                        columns.map(({ key }, index) => {
                                          const { span } = columns[index]
                                          // console.log({ key }, index)
                                          const style = index === 0 ? { paddingLeft: 0 } : {}
                                          return (
                                            <Col style={style} span={span} key={key}>
                                              <Item field={key} />
                                            </Col>
                                          )
                                        })
                                      }
                                      <Col flex="1 0 150px" >
                                        <div className="button-group">
                                          {recordAction.map((action) => {
                                            const isSimple = isString(action)
                                            const key = (isSimple ? action : action.key) ?? Math.random()
                                            const option = isSimple ? {} : action
                                            const operationDomMap = {
                                              delete: <DelButton key={key} remove={remove} index={index} actions={operation} options={option} fields={fields} />,
                                              up: <UpButton key={key} move={move} index={index} actions={operation} options={option} fields={fields} />,
                                              down: <DownButton key={key} move={move} index={index} actions={operation} options={option} fields={fields} />,
                                              drag: <DragButton key={key} options={option} index={index} {...provided.dragHandleProps} />
                                            }
                                            return operationDomMap[key] ?? null
                                          })}
                                        </div>
                                      </Col>
                                    </Row>
                                  </div>
                                </Item>
                              </div>
                            )
                          }}
                      </Draggable>
                    )
                  })}
                </div>)
            }
            }
          </Droppable>
        </DragDropContext>
      </div>
      {addAction && <AddButton options={addButtonProps} add={add} actions={operation} columns={columns} />}
      <Form.ErrorList errors={errors} />
    </div>
  )
}

export default ArrayItem
